use salvo::{handler, Request, Response};
use salvo::http::StatusCode;
use salvo::prelude::Json;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
pub struct Animal {
    pub name: String,
}
#[handler]
pub async fn animal_add(req: &mut Request, res: &mut Response) {
    let animal = req.parse_json::<Animal>().await;
    match animal {
        Ok(animal) => {
            res.render(Json(animal));
        }
        Err(_) => {
            res.status_code(StatusCode::BAD_REQUEST).body("参数解析错误");
        }
    }
}
#[handler]
pub async fn animal_put(req: &mut Request, res: &mut Response) {
    let animal = req.parse_form::<Animal>().await;
    match animal {
        Ok(animal) => {
            res.render(Json(animal));
        }
        Err(_) => {
            res.status_code(StatusCode::BAD_REQUEST).body("参数解析错误");
        }
    }
}

#[cfg(test)]
mod tests {
    use salvo::Service;
    use salvo::test::{ResponseExt, TestClient};
    use tokio::test;

    use crate::request::Animal;
    use crate::router;

    #[test]
    async fn test_animal_add() {
        let service = Service::new(router());
        let content = TestClient::post(format!("http://127.0.0.1:14300/animal"))
            .send(&service).await.take_string().await.unwrap();
        assert_eq!("参数解析错误", content);

        let animal = Animal { name: "大象".to_string() };
        let content = TestClient::post(format!("http://127.0.0.1:14300/animal")).json(&animal)
            .send(&service).await.take_string().await.unwrap();
        assert_eq!("{\"name\":\"大象\"}", content);
    }
    #[test]
    async fn test_animal_put() {
        let service = Service::new(router());
        let form = [("name", "老虎")];
        let content = TestClient::put(format!("http://127.0.0.1:14300/animal")).form(&form)
            .send(&service).await.take_string().await.unwrap();
        assert_eq!("{\"name\":\"老虎\"}", content);
    }
}